import 'package:flutter/material.dart';
import 'package:overlay_support/overlay_support.dart';
import 'package:wowhy/service_locator.dart';
import 'package:wowhy/services/navigate_service.dart';

import '../models/error_info.dart';
import '../assets/icons.dart';
import '../widgets/toast.dart';
import '../widgets/unpop_scope.dart';

import 'http.dart';

enum MessageType {
  success,
  error,
  info,
}

enum AlertActionButton {
  okCancel,
  yesNo,
  yesNoCancel,
}

enum AlertActionResult {
  ok,
  yes,
  no,
  cancel,
}

IconData _getMessageIcon(MessageType type) {
  switch (type) {
    case MessageType.error:
      return IconsAssets.error;

    case MessageType.info:
      return IconsAssets.info;

    case MessageType.success:
    default:
      return IconsAssets.success;
  }
}

Color _getMessageColor(MessageType type) {
  switch (type) {
    case MessageType.error:
      return Colors.redAccent;

    case MessageType.info:
      return Colors.yellowAccent;

    case MessageType.success:
    default:
      return Colors.blueAccent;
  }
}

class MessageUtil {
  static bool isLoadingShow = false;

  static void toast(
    BuildContext context,
    String msg, {
    MessageType type = MessageType.success,
  }) {
    showOverlay((context, t) {
      return Opacity(
        opacity: t,
        child: IosStyleToast(
          msg: msg,
          icon: _getMessageIcon(type),
        ),
      );
    });
  }

  static OverlaySupportEntry notification(
    BuildContext context,
    String msg, {
    MessageType type = MessageType.success,
  }) {
    return showSimpleNotification(
      Text(msg),
      background: _getMessageColor(type),
      leading: Icon(_getMessageIcon(type)),
    );
  }

  static Future<AlertActionResult> alert(
    BuildContext context,
    String content, {
    String title = '提示',
  }) {
    return showDialog(
          context: context,
          builder: (context) => UnpopScope(
            child: AlertDialog(
              title: Text(title),
              content: Text(content),
              actions: [
                FlatButton(
                  onPressed: () =>
                      getIt<NavigateService>().pop(AlertActionResult.ok),
                  child: Text('确定'),
                ),
              ],
            ),
          ),
        ) ??
        AlertActionResult.ok;
  }

  static Future<AlertActionResult> confirm(
    BuildContext context,
    String content, {
    String title = '提示',
    AlertActionButton buttons = AlertActionButton.yesNo,
  }) {
    List<Widget> actions = List<Widget>();
    AlertActionResult defaultResult;

    if (buttons == AlertActionButton.okCancel) {
      defaultResult = AlertActionResult.cancel;
      actions.addAll([
        FlatButton(
          onPressed: () => getIt<NavigateService>().pop(AlertActionResult.ok),
          child: new Text('确定'),
        ),
        FlatButton(
          onPressed: () => getIt<NavigateService>().pop(AlertActionResult.cancel),
          child: new Text('取消'),
        ),
      ]);
    } else {
      defaultResult = AlertActionResult.no;
      actions.addAll([
        FlatButton(
          onPressed: () => getIt<NavigateService>().pop(AlertActionResult.yes),
          child: new Text('是'),
        ),
        FlatButton(
          onPressed: () => getIt<NavigateService>().pop(AlertActionResult.no),
          child: new Text('否'),
        ),
      ]);

      if (buttons == AlertActionButton.yesNoCancel) {
        defaultResult = AlertActionResult.cancel;
        actions.add(FlatButton(
          onPressed: () => getIt<NavigateService>().pop(AlertActionResult.cancel),
          child: new Text('取消'),
        ));
      }
    }

    return showDialog(
          context: context,
          builder: (context) => UnpopScope(
            child: AlertDialog(
              title: Text(title),
              content: Text(content),
              actions: actions,
            ),
          ),
        ) ??
        defaultResult;
  }

  static void showLoading(
    BuildContext context, [
    String content = '',
  ]) {
    if (isLoadingShow) {
      return;
    }

    isLoadingShow = true;
    showDialog(
      context: context,
      builder: (context) => UnpopScope(
        child: Scaffold(
          backgroundColor: Colors.transparent,
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: <Widget>[
                // CircularProgressIndicator自带loading效果，需要宽高设置可在外加一层sizedbox，设置宽高即可
                CircularProgressIndicator(),
                SizedBox(
                  height: 10,
                ),
                Text(content),
              ],
            ),
          ),
        ),
      ),
    ).then((_) {
      isLoadingShow = false;
    });
  }

  static hideLoading(BuildContext context) {
    if (isLoadingShow) {
      getIt<NavigateService>().pop();
    }
  }

  static Future<T> blocking<T>(
    BuildContext context,
    Future<T> action(),
  ) async {
    try {
      MessageUtil.showLoading(context);
      T res = await action();
      MessageUtil.hideLoading(context);
      return res;
    } on HttpError catch (ex) {
      ErrorInfo errorInfo = ErrorInfo.fromHttpError(ex);

      MessageUtil.hideLoading(context);
      MessageUtil.toast(context, errorInfo.message, type: MessageType.error);

      throw errorInfo;
    } catch (ex) {
      MessageUtil.hideLoading(context);
      rethrow;
    }
  }
}
